<template>
  <div id="app">
    <Header ref="count" v-show="shoeHeader" />
    <transition name="move" mode="out-in">
      <keep-alive include="xzhi">
        <router-view />
      </keep-alive>
    </transition>
    <el-dialog
      :visible.sync="loadVisible"
      style="width:100%;position:absolute;top:-15vh"
      :show-close="false"
      custom-class="customWidth"
    >
      <div class="loadEffect">
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
      </div>
      <h4
        style="text-align:center;color:white;text-shadow: 0px 2px 5px #020202;"
      >
        人脸验证识别中......
        <br />（请您摘下眼镜,正视前方摄像机!）
        <br />
        <span>{{ miao2 }}秒后自动消失!</span>
      </h4>
    </el-dialog>
    <!-- 弹出考试信息 -->
    <el-dialog title="考生信息" :visible.sync="examInfor" width="45%">
      <div class="ksimg">
        考生图片：
        <img
          :src="'platform/images/' + $store.state.studentIdCard + '.jpg'"
          alt
        />
      </div>
      <div>考生姓名： {{ $store.state.studentName }}</div>
      <div>设备名称： {{ $store.state.equipmentName }}</div>
      <div>考试名称： {{ $store.state.examinationName }}</div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="examInfor = false">取 消</el-button>
        <el-button type="primary" @click="endter">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 考生结束弹窗 -->
    <el-dialog
      title="提 示"
      :visible.sync="EndVisible"
      :before-close="endDlogClose"
      width="30%"
    >
      <span
        >本场{{ $store.state.examType == 1 ? "考试" : "培训" }}已结束!!</span
      >
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="endBut">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 出现错误考生 -->
    <el-dialog title="警告" :visible.sync="ErrVisible" width="40%">
      <i class="el-icon-warning" style="color:red"></i> 警告！考生
      <span style="color:red">{{ errname }}</span>
      ,请前往
      <span style="color:red">{{ errEquipment }} !</span>
      <span slot="footer" class="dialog-footer">
        <span style="font-size:.11rem;color:#888">{{ miao }}秒后自动关闭</span>
      </span>
    </el-dialog>
    <!-- 提示位置错误 -->
    <audio src="staic/tswz.mp3" ref="tswz"></audio>
    <!-- 检测完成语音 -->
    <audio src="staic/jcwc.mp3" ref="jcwc"></audio>
    <!-- 提示输入学号开始培训 -->
    <audio :src="srpxSrc" ref="srpx"></audio>

    <el-button type="warning" plain @click="ssx" class="reloadbtn"
      >重 新 加 载</el-button
    >
    <alert :warndata="warndata" />
  </div>
</template>

<script>
import Alert from "@/components/Alert";
import Header from "@/components/Header";
// import Home from "@/views/Home";

export default {
  components: { Alert, Header },
  data() {
    return {
      loadVisible: false,
      miao2: 200,
      miaoInterval: null, // 出现错误考生信息 倒计时
      miaoInterval2: null,
      examInfor: false, // 弹出考生信息
      EndVisible: false, // 结束考试/培训弹窗
      shoeHeader: false, // header组件显示与隐藏
      reconnectData: null,
      lockReconnect: false, //避免重复连接，因为onerror之后会立即触发 onclose
      timeout: 30000, //30s一次心跳检测
      websock: null,
      timeoutObj: null,
      serverTimeoutObj: null,
      errname: "", //错误考生
      errEquipment: "", //正确机器
      miao: 20,
      ErrVisible: false,
      rid: "",
      warndata: [],
      xzhishow: false, //须知页面 flase 显示主界面
      endPath: "", // 监听后的路由
      clearTimeQueryinfor: null, // 定时请求 queryinfor
      clearEndTestTime: null, //结束考试定时
      srpxSrc: require("@/assets/srpx.mp3"),
    };
  },
  computed: {},
  watch: {
    $route: {
      handler: function(route) {
        // this.endPath = route.path;
        console.log(route.path);
        switch (route.path) {
          case "/home":
            this.shoeHeader = false;
            break;
          case "/xzhi":
            this.shoeHeader = false;
            break;
          case "/train":
            this.shoeHeader = true;
            this.$store.state.studentName ? this.$refs.count.countDown() : "";
            clearTimeout(this.clearTimeQueryinfor);
            break;
          case "/verify":
            this.shoeHeader = true;
            clearTimeout(this.clearTimeQueryinfor);
            break;
          default:
            break;
        }
        route.path == "/"
          ? (document.querySelector("body").style.backgroundColor = "#006669")
          : (document.querySelector("body").style.backgroundColor = "#f3ffff");
      },
      immediate: true,
    },
  },
  mounted() {
    this.queryInfor();
    this.$axios
      .post("platform/NetSDK/getEquipment")
      .then((res) => {
        this.$store.commit("setNewDate", res.headers.date);
        let data = JSON.parse(res.data.data);
        if (res.data.result_code == 200) {
          this.rid = data.equipment;
          this.$store.commit("setEquipmentId", data.equipment);
          let wsurl = `wss://${data.ip}:${data.port}/api/websocket/${data.equipment}`;
          this.init(wsurl);
        }
      })
      .catch(() => {
        this.warndata = [1, "网络错误", 2500];
      });
  },
  methods: {
    ssx() {
      // window.location.reload();
      this.$router.go(0);
    },
    // websoket
    init(wsurl) {
      if (typeof WebSocket === "undefined") {
        alert("您的浏览器不支持webSocket");
      } else {
        this.websock = new WebSocket(wsurl);
        this.websock.onopen = this.websocketonopen; //连接成功
        this.websock.onmessage = this.websocketonmessage; //广播成功
        this.websock.onerror = this.websocketonerror; //连接断开，失败
        this.websock.onclose = this.websocketclose; //连接关闭
      }
    }, //初始化weosocket
    websocketonopen() {
      this.heatBeat();
    }, //连接成功
    websocketonerror() {
      console.log("websoket链接错误");

      if (this.rid !== "") {
        this.reconnect();
      }
    }, //连接失败
    websocketclose() {
      console.log("websoket连接关闭");
      if (this.rid !== "") {
        this.reconnect();
      }
    }, //各种问题导致的 连接关闭
    websocketonmessage(msg) {
      this.heatBeat(); //收到消息会刷新心跳检测，如果一直收到消息，就推迟心跳发送
      let data = JSON.parse(msg.data);
      console.log(data);
      if (data.type == "heart") {
        return;
      }

      if (data.type == 1) {
        //出现非本机考生
        this.errEquipment = data.equipmentName;
        this.errname = data.studentName;
        if (!this.ErrVisible) {
          this.$refs.tswz.play();
          this.miao = 20;
          this.ErrVisible = true;
          this.miaoInterval = setInterval(() => {
            this.miao = --this.miao;
            if (this.miao <= 0) {
              this.ErrVisible = false;
            }
          }, 1000);
        }
      } else if (data.type == 2) {
        //结束考试
        this.loadVisible = false;
        this.examInfor = false;
        this.EndVisible = true;
        this.$store.commit("setKsksDisable", false);
        this.$store.commit("setStudentName", "");
        this.clearEndTestTime = setTimeout(() => {
          this.EndVisible = false;
          this.queryInfor();
        }, 6e4);
        localStorage.setItem("millis", 0);
      } else if (data.type == 3) {
        // 开始人脸识别
        this.$router.push("/train");
        // this.shoeHeader = true;
        this.face();
        this.$store.commit("setExamType", Number(data.examType));
      } else if (data.requestType == "startTrain") {
        this.clearTimeQueryinfor && clearTimeout(this.clearTimeQueryinfor);
        this.$store.commit("setExamType", 0);
        this.$refs.srpx.play();
        this.$router.push("/verify");
      } else if (data.requestType == "stopTrain") {
        this.warndata = [2, "培训时间结束", 3200]; // 培训结束 切回到初始页面
        this.$router.push("/");
        setTimeout(() => {
          this.$router.go(0);
        }, 28000);
      } else {
        // 正确的考生出现
        this.miaoInterval2 && clearInterval(this.miaoInterval2);
        this.loadVisible = false;
        this.ErrVisible = false;
        this.miaoInterval && clearInterval(this.miaoInterval);
        this.$store.commit("setStudentName", data.studentName);
        this.$store.commit("setStudentId", data.studentId);
        this.$store.commit("setStudentIdCard", data.studentIdCard);
        this.$store.commit("setExaminationName", data.examinationName);
        this.$store.commit("setEquipmentName", data.equipmentName);
        this.$store.commit("setEndTime", data.endTime);
        this.$store.commit("setExamType", Number(data.examType));

        this.examInfor = true;
        this.$refs.jcwc.play();
        let that = this;
        if (data.type == 4) {
          setTimeout(() => {
            that.examInfor = false;
          }, 165000);
        }
      }
    }, //数据接收
    websocketsend(data) {
      this.websock.send(JSON.stringify(data));
    }, //数据发送
    reconnect() {
      if (this.lockReconnect) {
        return; //这里很关键，因为连接失败之后之后会相继触发 连接关闭，不然会连接上两个 WebSocket
      }
      this.lockReconnect = true;
      this.reconnectData && clearTimeout(this.reconnectData);
      this.reconnectData = setTimeout(() => {
        this.init();
        this.lockReconnect = false;
      }, 5000);
    },
    heatBeat() {
      this.timeoutObj && clearTimeout(this.timeoutObj);
      this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
      this.timeoutObj = setTimeout(() => {
        this.websocketsend({ type: "heart" }); //根据后台要求发送
        this.serverTimeoutObj = setTimeout(() => {
          this.websock.close(); //如果  30秒之后我们没有收到 后台返回的心跳检测数据 断开socket，断开后会启动重连机制
        }, 2000);
      }, this.timeout);
    }, //心跳检测

    // 人脸识别中 函数封装
    face() {
      this.miaoInterval2 && clearInterval(this.miaoInterval2);
      this.miao2 = 200;
      this.loadVisible = true;
      this.miaoInterval2 = setInterval(() => {
        this.miao2 = --this.miao2;
        if (this.miao2 <= 0) {
          clearInterval(this.miaoInterval2);
          this.loadVisible = false;
        }
      }, 1000);
    },

    // 定时请求 考试信息
    queryInfor() {
      // return new Promise((resolve, reject) => {
      this.$axios
        .get("platform/faceIdentify/stateDetection")
        .then((res) => {
          this.$store.commit("setNewDate", res.headers.date);
          if (res.data.result_code == 200) {
            // trainMode>>培训模式  trainModeDetection>>培训进行中   detection>>考试进行中 face>>人脸识别中
            let msg = res.data.msg;
            let examData = JSON.parse(res.data.data);
            msg.includes("train")
              ? this.$store.commit("setExamType", 0)
              : this.$store.commit("setExamType", 1);

            msg.toLowerCase().includes("detection")
              ? (() => {
                  this.$store.commit("setStudentName", examData.studentName);
                  this.$store.commit("setStudentId", examData.studentId);
                  this.$store.commit("setEndTime", examData.endTime);
                  this.$store.commit(
                    "setExaminationName",
                    examData.examinationName
                  );
                  this.$store.commit(
                    "setEquipmentName",
                    examData.equipmentName
                  );
                  this.$store.commit(
                    "setStudentIdCard",
                    examData.studentIdCard
                  );
                  this.warndata = [
                    2,
                    `${
                      this.$store.state.examType == 1 ? "开始考试" : "培训开始"
                    }`,
                    2500,
                  ];
                  this.$refs.count.countDown();
                })()
              : "";
            msg == "face" ? this.face() : "";
            // this.shoeHeader = true;
            msg == "trainMode"
              ? (this.$router.push("/verify"), this.$refs.srpx.play())
              : this.$router.push("/train");
            // resolve("1");
            return;
          } else {
            this.$router.push("/");
            this.clearTimeQueryinfor = setTimeout(() => {
              this.queryInfor();
            }, 1000 * 5);
            // resolve("2");
            return;
          }
        })
        .catch((err) => {
          console.log(err);
          this.warndata = [1, "网络错误", 2500];
          this.$router.push("/");
          this.clearTimeQueryinfor = setTimeout(() => {
            this.queryInfor();
          }, 1000 * 60 * 5);
          // reject();
        });
      // });
      // this.$router.push("/");
    },
    endter() {
      this.$refs.count.countDown();
      this.examInfor = false;
    },
    endDlogClose(done) {
      clearTimeout(this.clearEndTestTime);
      this.queryInfor();
      done();
    },
    endBut() {
      this.EndVisible = false;
      clearTimeout(this.clearEndTestTime);
      this.queryInfor();
    },
  },
};
</script>

<style>
body {
  box-sizing: border-box;
}
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  box-sizing: border-box;
  text-align: center;
  color: #2c3e50;
  padding: 0.37rem 0.113rem 0;
}
body,
ul,
li,
h1,
h2,
h3,
p,
dd,
dt,
h4 {
  margin: 0;
  padding: 0;
}

a {
  text-decoration: none;
}

li {
  list-style: none;
}
button {
  outline: none;
  border: none;
  border-radius: 10px;
}

button:focus {
  outline: none;
}
button::-moz-focus-inner {
  border-color: transparent;
}
input {
  outline: none;
  border: 1px solid #ccc;
}
/* input:focus {
  border: none;
} */
select {
  /*将默认的select选择框样式清除*/
  appearance: none;
  -moz-appearance: none;
  -webkit-appearance: none;
}
.xh {
  margin-top: 0.3rem;
  font-weight: bold;
  font-size: 45px;
  line-height: 65px;
  box-sizing: border-box;
}
.xh i {
  background: #ffffff;
  line-height: 65px;
  border: 1px solid #ccc;
  width: 5.8%;
  border-radius: 10px 0 0 10px;
}
.xh input {
  height: 64px;
  line-height: 65px;
  padding: 0 10px;
  font-size: 35px;
  line-height: 45px;
  width: 54%;
  border-radius: 0 10px 10px 0;
  font-weight: bold;
  vertical-align: bottom;
  border-left: none;
}
.xh button {
  margin: 0.3rem 0 0 0;
  box-sizing: border-box;
  font-size: 28px;
  width: 61.8%;
  padding: 15px 30px;
  background: #008080;
  color: white;
}
.list {
  display: flex;
  justify-content: space-around;
}
.list button {
  padding: 0.28rem;
  margin-bottom: 0.9rem;
  background: #008080;
  color: white;
  font-size: 0.3rem;
  border: none;
  letter-spacing: 0.03rem;
  font-weight: 600;
  border-radius: 0.12rem;
}

.list .colo {
  background: #855b43;
}
.list .redd {
  background: #eee;
}
.list:last-child button {
  margin-bottom: 0;
}
.ksxz {
  padding: 0.2rem;
  width: 75%;
  position: fixed;
  top: 5%;
  left: 50%;
  z-index: 22;
  background: #ffffff;
  box-shadow: 0 0 0.05rem #6d6d6d57;
  transform: translateX(-50%);
}
.ksxz h1 {
  margin-bottom: 0.15rem;
}
.ksxz p {
  text-align: left;
  margin: 15px 20px;
  font-size: 0.15rem;
}
.ksxz button {
  padding: 0.08rem 0.16rem;
  background: #008080;
  color: white;
  font-size: 0.18rem;
  border: none;
  border-radius: 0.07rem;
  width: 25%;
}
.ksimg {
  line-height: 0.38rem;
}
.el-dialog__body {
  padding: 0.1rem 0.15152rem;
}
.el-dialog div {
  font-size: 0.25rem;
  font-weight: bold;
  margin-bottom: 0.15rem;
}
.el-dialog__header span {
  font-size: 0.2rem;
}
.el-dialog__headerbtn {
  top: 0.08rem;
  font-size: 0.2rem;
}
.ksimg img {
  width: 0.6rem;
  height: 0.6rem;
  vertical-align: middle;
}
.el-dialog .el-dialog__footer {
  text-align: right;
}
.el-dialog__footer .el-button {
  font-size: 0.16rem;
}
.el-message-box {
  width: 5.5rem;
}
.el-message-box__headerbtn {
  font-size: 0.3rem;
}
.el-message-box__title {
  font-size: 0.3rem;
}
.el-message-box__content,
.el-message-box__status {
  font-size: 0.3rem !important;
}
.el-message-box__container {
  font-size: 0.3rem;
}
.el-message-box__message p {
  line-height: 1.5em;
}
.el-message-box__btns button:nth-child(2) {
  margin-left: 0.15rem;
}
.el-button--small {
  font-size: 0.22rem;
}
.customWidth {
  background: none;
  box-shadow: none;
  width: 100%;
  height: 87%;
}
.el-dialog.customWidth {
  margin: 0;
}
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background: #ccc !important;
}
.reloadbtn {
  position: absolute;
  top: 25px;
  right: 25px;
  opacity: 0.1;
}
.photo {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  background: #00000080;
}
/* .photo button {
  position: absolute;
  z-index: 1200;
  top: 85%;
  left: 55%;
  font-size: 35px;
  border: none;
}
.photo button:last-child {
  left: 65%;
} */
.el-button--primary {
  background-color: #008080;
}
.videos {
  position: absolute;
  z-index: 999;
  width: 70%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.canvas {
  position: absolute;
  z-index: 1305;
  width: 70%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.loadEffect {
  width: 100px;
  height: 100px;
  position: relative;
  margin: 0 auto;
  margin-top: 100px;
}
.loadEffect span {
  display: inline-block;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: white;
  position: absolute;
  animation: load 1.04s ease infinite;
}
@keyframes load {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0.2;
  }
}
.loadEffect span:nth-child(1) {
  left: 0;
  top: 50%;
  margin-top: -8px;
  animation-delay: 0.13s;
}
.loadEffect span:nth-child(2) {
  left: 14px;
  top: 14px;
  animation-delay: 0.26s;
}
.loadEffect span:nth-child(3) {
  left: 50%;
  top: 0;
  margin-left: -8px;
  animation-delay: 0.39s;
}
.loadEffect span:nth-child(4) {
  top: 14px;
  right: 14px;
  animation-delay: 0.52s;
}
.loadEffect span:nth-child(5) {
  right: 0;
  top: 50%;
  margin-top: -8px;
  animation-delay: 0.65s;
}
.loadEffect span:nth-child(6) {
  right: 14px;
  bottom: 14px;
  animation-delay: 0.78s;
}
.loadEffect span:nth-child(7) {
  bottom: 0;
  left: 50%;
  margin-left: -8px;
  animation-delay: 0.91s;
}
.loadEffect span:nth-child(8) {
  bottom: 14px;
  left: 14px;
  animation-delay: 1.04s;
}
</style>
